﻿#region Copyright

// // The contents of this file are subject to the Mozilla Public License
// // Version 1.1 (the "License"); you may not use this file except in compliance
// // with the License. You may obtain a copy of the License at
// //   
// // http://www.mozilla.org/MPL/
// //   
// // Software distributed under the License is distributed on an "AS IS"
// // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// // License for the specific language governing rights and limitations under 
// // the License.
// //   
// // The Initial Developer of the Original Code is Robert Smyth.
// // Portions created by Robert Smyth are Copyright (C) 2008-2013.
// //   
// // All Rights Reserved.

#endregion

namespace NoeticTools.NWorkflow
{
    /// <summary>
    ///     Work flow run child workflow if activity returns grant result.
    /// </summary>
    public class ConditionalRunWorkFlowRules<TCondition, T> : WorkflowRules<T>
    {
        private readonly IActivity<TCondition> _getPermissionActivity;
        private readonly TCondition _grantValue;
        private readonly IWorkflow<T> _innerWorkflow;
        private readonly T _onDenied;

        public ConditionalRunWorkFlowRules(IActivity<TCondition> getPermissionActivity, IWorkflow<T> innerWorkflow, TCondition grantValue, T onDenied) : base("")
        {
            _getPermissionActivity = getPermissionActivity;
            _innerWorkflow = innerWorkflow;
            _grantValue = grantValue;
            _onDenied = onDenied;
        }

        protected override void BuildWorkflow()
        {
            base.BuildWorkflow();

            OnBegin.EnterStep("Condition");

            using (var x = AddStep<TCondition>("Condition"))
            {
                x.OnEntry.Start(_getPermissionActivity);
                x.OnResult(_grantValue).TransitionTo("Run");
                x.OnAnyUnhandledResult.Exit(_onDenied);
            }

            using (var x = AddStep<T>("Run"))
            {
                x.OnEntry.Start(_innerWorkflow);
                x.ExitWithAnyResult<T>();
            }
        }
    }
}